﻿///////////////////////////////////////////////////////////////////////////////
// 文件名： D3D9RenderWindow.cc
// 作者：   671643387@qq.com
// 日期：   2015年11月2日 下午4:16:27
// 简介：    
///////////////////////////////////////////////////////////////////////////////

#include <cassert>

#include "D3D9RenderWindow.hpp"
using namespace ::dx9::render;

#define CLASS_NAME  L"D3D9RenderWindow_Class"

D3D9RenderWindow::D3D9RenderWindow()
    : hModule_(::GetModuleHandleW(NULL))
    , hWnd_(NULL)
    , eventDelegate_(NULL)
    , title_(L"D3D9RenderWindow")
{

}

D3D9RenderWindow::~D3D9RenderWindow()
{

}

///////////////////////////////////////////////////////////////////////////////

void D3D9RenderWindow::SetTitle(::graphics::string title)
{
    assert(hWnd_ != NULL && !title.empty());
    title_ = title;
    ::SetWindowTextW(hWnd_, title_.c_str());
}

::graphics::string D3D9RenderWindow::GetTitle() const
{
    return title_;
}

///////////////////////////////////////////////////////////////////////////////

void D3D9RenderWindow::SetEventDelegate(::graphics::EventDelegate* delegate)
{
    assert(delegate != NULL);
    eventDelegate_ = delegate;
}

HWND D3D9RenderWindow::GetHWND() const
{
    return hWnd_;
}

bool D3D9RenderWindow::Initialize()
{
    ::graphics::graphics::render::RenderWindow::stProperties properties;
    ZeroMemory(&properties, sizeof(properties));

    eventDelegate_->OnPreCreateRenderWindow(properties);

    if (!RegisterClass_(properties))
        return false;

    if (!CreateWindow_(properties))
        return false;

    return true;
}

void D3D9RenderWindow::Show()
{
    assert(hWnd_ != NULL);
    eventDelegate_->OnRenderWindowShouldShow(this);
    ::UpdateWindow(hWnd_);
    ::ShowWindow(hWnd_, SW_SHOW);
}

///////////////////////////////////////////////////////////////////////////////

bool D3D9RenderWindow::RegisterClass_(::graphics::graphics::render::RenderWindow::stProperties& properties)
{
    WNDCLASSEXW wcex;
    ZeroMemory(&wcex, sizeof(wcex));

    wcex.cbSize = sizeof(wcex);
    wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
    wcex.hCursor = ::LoadCursorW(hModule_, properties.cursor);
    wcex.hIcon = ::LoadIconW(hModule_, properties.icon);
    wcex.hIconSm = ::LoadIconW(hModule_, properties.iconSmall);
    wcex.hInstance = hModule_;
    wcex.lpfnWndProc = &(D3D9RenderWindow::WndProc);
    wcex.lpszClassName = CLASS_NAME;
    wcex.lpszMenuName = NULL;
    wcex.style = CS_VREDRAW | CS_HREDRAW;

    return (0 != ::RegisterClassExW(&wcex));
}

bool D3D9RenderWindow::CreateWindow_(::graphics::graphics::render::RenderWindow::stProperties& properties)
{
    title_ = properties.title;

    int x = CW_USEDEFAULT;
    int y = CW_USEDEFAULT;

    if (properties.centerScreen)
    {
        int screenW = ::GetSystemMetrics(SM_CXSCREEN);
        int screenH = ::GetSystemMetrics(SM_CYSCREEN);
        x = (screenW - properties.width) / 2;
        y = (screenH - properties.height) / 2;
    }

    hWnd_ = ::CreateWindowExW(0,
        CLASS_NAME,
        title_.c_str(),
        WS_OVERLAPPEDWINDOW,
        x,
        y,
        properties.width,
        properties.height,
        NULL,
        NULL,
        hModule_,
        NULL);

    return (hWnd_ != NULL);
}

///////////////////////////////////////////////////////////////////////////////

LRESULT D3D9RenderWindow::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    switch(uMsg)
    {
    case WM_DESTROY:
        ::DestroyWindow(hWnd);
        ::PostQuitMessage(0);
    }
    return ::DefWindowProcW(hWnd, uMsg, wParam, lParam);
}